import React, { createRef, forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react";
/* 
useRef可获取DOM元素也可以获取子组件实例
如果是一个类组件，我们为其设置ref，可以得到子组件的实例,如果是函数组件，直接设置ref会报错
函数组件如何设置ref：
1.通过forwardRef进行ref转发，用forward把函数组件包裹，第二个参数为初始设置的ref，可把该参数赋值给函数组件内部某个元素上

*/
class Clid extends React.Component{
  render(){
    return <div>
      <p>这是类子组件</p>
    </div>
  }
}
const Child=forwardRef(function Child(props,ref){
  const submit=()=>{
    //.....
  }
  useImperativeHandle(ref,()=>{
    return{//return的对象会赋值给父组件ref对象的current属性，即父组件获取函数组件中的方法
      submit,
      name:'Child'
    }
  })
  return <div>
    <p ref={ref}>这是函数子组件</p>
  </div>
})
let prev;
export default function Useref(){
  let [num,setNum]=useState(0)
  let btnBox=useRef(null)//true
  //let btnBox=createRef(null);//false
  let pBox = useRef(null);
  let pBox2=useRef(null);
  if(!prev){
    prev=btnBox
  }else(
    console.log(prev===btnBox)
  )
  //btnBox.current的值为当前DOM对象
  useEffect(()=>{
    console.log(btnBox.current);
  },[])

  return <div>
    {num}
    <button ref={btnBox} onClick={()=>{setNum(100)}}>按钮ref</button>
    <Clid ref={pBox}></Clid>
    <Child ref={pBox2}></Child>

  </div>
}

/* 
useRef和createRef(类组件和函数组件都能用)用法相同，其不同点在于：
 + createRef每次渲染都会返回一个新的引用
 + useRef每次都会返回相同的引用
*/